<?php

namespace Ldy\Traits\Form;

trait Main{

    /**
     * 获取表单元素
     *
     * @return array
     */
    public function getForm(){
        $res = $this->form;
// print_r($this->form['rule']);
        $pk = $this->model->getPk();
        $rule = [
            //表主键名
            ["type"=>"hidden","field"=>"__pk","value"=> $pk],
            //主键值
            ["type"=>"hidden","field"=>$pk,"value"=> $this->id ? $this->id:'']
        ];

        if(!empty($this->formGroup)){
            //分组
            $res['rule'] = $this->formGroup;
            foreach($rule as $item) $res['rule'][0]['rule'][] = $item;
        }else if(!empty($this->rows)){
            //分列
            $res['rule'] = $this->rows;
            foreach($rule as $item) $res['rule'][] = $item;
        }else{
            //通用
            foreach($this->form['rule'] as $item) $rule[] = $item;
            $res['rule'] = $rule;
        }
        
        //清空数据
        $this->form = ["is_group"=>false,"rule"=>[],"options"=>$this->options];

        return $res;
    }

     /**
     * 获取表数据模型
     *
     * @return Model
     */
    public function model(){
        return $this->model;
    }

    /**
     * 表单数据保存
     *
     * @param array $postData
     * @return Model
     */
    public function save($postData){

        if(($response = $this->__checkUnique($postData))) return $response;

        $this->model->data($postData, true);

        //生成后端数据验证规则
        $this->__generateServerValidateRule();

        // $this->model->getRule();
        
        if(($response = $this->callSaving())) return $response;

        $checkData = $this->model->validateData($postData);
        
        if($checkData !== true) return $checkData;

        $this->model->save();
        
        if(($response = $this->callSaved())) return $response;

        return $this->model;
    }

    public function update($id, $postData){

        $upDateFields = [];

        foreach($postData as $k=>$v){
            //唯一字段，特殊处理字段跳过不更新数据
            if(in_array($k, $this->uniqueFields) || $k=="__pk") continue;
            //隐藏的字段跳过验证，跳过更新
            if(in_array($k, $this->model->getHiddenFields())) continue;

            $upDateFields[] =$k;
        }
        
        $this->model->appendData($postData, true);

        //生成后端数据验证规则
        $this->__generateServerValidateRule();

        if(($response = $this->callBeforeUpdate())) return $response;

        $checkData = $this->model->validateData($postData);
        
        if($checkData !== true) return $checkData;

        $pk = $this->model->getPk();

        //获取更新白名单数据和字段
        if(!empty($this->model->updateWhiteList)){
             $upDateFields = $this->model->updateWhiteList + $upDateFields;
             foreach($this->model->updateWhiteList as $v) $postData[$v] = $this->model->getAttr($v);
        }

        $this->model->update($postData, [$pk=>$id], $upDateFields);

        if(($response = $this->callAfterUpdate())) return $response;

        return $this->model;
    }

    /**
     * 验证数据字段唯一性，不能重复的字段值
     *
     * @param [type] $postData
     * @return void
     */
    protected function __checkUnique($postData){
        if(empty($this->uniqueFields)) return false;

        $model = $this->model;

        foreach($this->uniqueFields as $field) $model = $model->whereOr($field, $postData[$field]);

        $res = $model->select();
        
        if($res->isEmpty()) return false;

        $data = $res->toArray();
        $error = [];
        foreach($data as $item){
            foreach($this->uniqueFields as $field){
                $rule = $this->form['rule'][$field];
                if($item[$field] == $postData[$field]) $error[] = $rule['title'].'已存在！';
            }
        }

        return implode(',',$error);
    }
    /**
     * 通过前端数据验证规则，生成后端数据验证规则
     *
     * @param Array $rules
     * @return void
     */
    protected function __generateServerValidateRule(){
         //前端验证字段=>后端验证字段
         $ruleAttr = ['required=>require','type','min','max','len'];

         $rules = $this->form['rule'] + $this->controlElement;

         foreach($rules as $name => $rule){
             $validate = $rule['validate'];
             if(empty($validate)) continue;
             //隐藏的字段跳过验证，跳过更新
             if(in_array($name, $this->model->getHiddenFields())) continue;

             $itemRule = [];
             foreach($validate as $item){
                 foreach($ruleAttr as $attrs){
 
                     $msgKey = '';
                     $tmp = explode("=>", $attrs);
 
                     $attr = $tmp[0];
                     $useAttr = isset($tmp[1]) ? $tmp[1]: $attr;
 
                     if(!isset($item[$attr])) continue;
 
                     switch ($attr){
                         case "required":
                             $msgKey = $name.'.'.$useAttr;
                             $itemRule[] = $useAttr;
                             break;
                         case "min":
                         case "max":
                         case "len":
                             $itemRule[$attr] = $item[$attr];
                             $msgKey = $name.'.'.$attr;
                             break;
                         case "type":
                             $msgKey = $name.'.'.$item[$attr];
                             $itemRule[] = $item[$attr];
                             break;
                     }
                     
                     if($msgKey && $item['message']){
                         $message = empty($item[$msgKey]) ? $item['message']:$item[$msgKey];
                         $this->model->setRuleMessage($msgKey, $message);
                     }
                     
                 }
             }
             if($rule['effect'] && isset($rule['effect']['required']) && !in_array('require', $itemRule)) array_unshift($itemRule,"require");
             $this->model->setRule($name, $itemRule);
         }
    }

    /**
     * 更新合拼规则
     *
     * @param array $arr
     * @return void
     */
    protected function __updateRule(Array $arr=[], $currFieldName = ''){
        $pointer = empty($currFieldName) ? $this->currFieldName:$currFieldName;
        $this->form['rule'][$pointer] = $this->__merge($this->form['rule'][$pointer], $arr);
    }

    protected function __addRule($fieldName, $title, $arr = []){

        $fieldName = (!empty($this->objectField) ? "{$this->objectField}.":'').$fieldName;
        //元素指针
        $this->currFieldName = $fieldName;

        if(!empty($fieldName)) $arr['field'] = $fieldName;
        if(!empty($title)) $arr['title'] = $title;
        if(!empty($this->resources) && isset($this->resources[$this->currFieldName])) $arr['value'] = $this->resources[$this->currFieldName];
        
        $itemElement = $this-> __merge($this->rule, $arr);

        if($itemElement['type'] == 'el-divider' || $itemElement['type'] == 'el-alert') unset($itemElement['field']);

        $this->form['rule'][$fieldName] = $itemElement;

        //保存给对象组
        $this->objectGroup[$fieldName] = $itemElement;

        //保存给可新增的数组元素
        $this->arrayElement[$fieldName] = $itemElement;
    }

    /**
     * 获取当前元素属性
     *
     * @param string $key
     * @return void
     */
    protected function __getCurrRule(String $key = ''){
        $currElement = $this->form['rule'][$this->currFieldName];
        return empty($key) ? $currElement:$currElement[$key];
    }

    /**
     * 第二个数组值覆盖第一个数组
     * 递归合拼数据
     */
    protected function __merge(Array $arr1, Array $arr2){
        
        foreach($arr2 as $key => $field){
            if(is_array($field)){
                if(isset($arr1[$key])){
                    $arr1[$key] = $this->__merge($arr1[$key], $field);
                }else{
                    $arr1[$key] = $field;
                }
            }else{
                $arr1[$key] = $field;
            }
        }

        return $arr1;
    }

}